<template></template>

<script lang="ts" setup>
import { baseUrl } from "@/utils/env"
import { onMounted, ref } from "vue"
import { getSoundConfig } from "@/utils/config"
import { useSound } from "@vueuse/sound"
import _ from "lodash"
import fetch from "@/api/fetch.js"
import useAppStore from "@/pinia"
const app = useAppStore() // pinia实例

// 是否是生产环境
let isProd = process.env.NODE_ENV === "production"
// 线上音频列表
const soundList = [] as Array<any>
const bgmList = [] as Array<any>
// 本地音频列表(已压缩)
const localSoundList = [] as Array<any>
const localBgmList = [] as Array<any>
// 所有音频
const audioList = [
    "ac.wav",
    "audio1.wav",
    "audio2.wav",
    "audio3.wav",
    "audio4.wav",
    "audio5.wav",
    "audio6.wav",
    "audio7.wav",
    "audio8.wav",
    "audio9.mp3",
    "audio10.mp3",
    "audio11.mp3",
    "audio12.mp3",
    "audio13.mp3",
    "audio14.mp3",
    "b-index.wav",
    "b-lobby.wav",
    "b-singleplay.wav",
    "b-singleplay01.wav",
    "button_c.wav",
    "button_h.wav",
    "c1.wav",
    "c2.wav",
    "c3.wav",
    "c4.wav",
    "c4b.wav",
    "dangerus.wav",
    "dangerus1.wav",
    "down.wav",
    "gameover.wav",
    "harddrop.wav",
    "hold.wav",
    "holdFail.wav",
    "move.wav",
    "movefail.wav",
    "r1.mp3",
    "r2.mp3",
    "r3.mp3",
    "r4.mp3",
    "r5.mp3",
    "r6.mp3",
    "r7.mp3",
    "r8.mp3",
    "r9.mp3",
    "r10.mp3",
    "r11.mp3",
    "r12.mp3",
    "r13.mp3",
    "r14.mp3",
    "r15.mp3",
    "r16.mp3",
    "r17.mp3",
    "r18.mp3",
    "r19.mp3",
    "r20.mp3",
    "rotate.wav",
    "rotatefail.wav",
    "t1.wav",
    "t1b.wav",
    "t2.wav",
    "t2b.wav",
    "t3.wav",
    "t3b.wav",
    "win.wav",
    "win-single.wav",
]

// 初始化音频资源列表
const initAudio = () => {
    // 引入@/assets/bgm下的所有文件
    const modules = import.meta.glob("@/assets/bgm/*")
    Object.keys(modules).forEach((key) => {
        // 匹配wav或者MP3
        let format = /\.(wav|mp3)$/i
        let name = key.split(format)[0].split("/").pop() as string
        // 生产环境 剔除'/src' '/bgm'
        if (isProd) {
            key = key.replace("/src", "")
            key = key.replace("/bgm", "")
        }
        let url = key
        let isBgm = name.indexOf("b-") != -1
        if (isBgm) {
            name = name.replace("b-", "")
            localBgmList.push({
                name,
                url,
            })
        } else {
            localSoundList.push({
                name,
                url,
            })
        }
    })

    console.log("localBgmList", localBgmList)
    console.log("localSoundList", localSoundList)

    audioList.forEach((name) => {
        let url = ""
        let isBgm = name.indexOf("b-") != -1
        if (isBgm) {
            url = baseUrl + "bgm/" + name
            name = name.replace("b-", "")
            name = name.replace(".wav", "").replace(".mp3", "") // 去掉格式
            bgmList.push({
                name,
                url,
            })
        } else {
            url = baseUrl + "bgm/" + name
            name = name.replace(".wav", "").replace(".mp3", "") // 去掉格式
            soundList.push({
                name,
                url,
            })
        }
    })
    console.log("bgmList", bgmList)
    console.log("soundList", soundList)
}

class AudioBase {
    localPlayList = [] as any
    localBgmList = [] as any
    targetBgm = null as any
    targetBgmName = ""
    battleBgmName = ""
    bgmVolume = 0.5
    soundVolume = 0.5
    // 本地资源加载完成进度
    localAudioNumber = 0
    loadLocalAudioNumber = 0
    loadProgress = ref(0) // 进度 百分比
    onLoadCallback: () => void = () => {}
    hasActionOnLoadCallback: boolean = false // 是否已经执行过onLoadCallback
    battleBgmList = [] as any

    constructor() {
        this.init()
    }

    init() {
        console.log("AudioBase init")
        this.localPlayList = []
        this.localBgmList = []
        this.targetBgm = null
        this.targetBgmName = ""
        this.battleBgmName = ""
        this.battleBgmList = []
        let config = getSoundConfig()
        // 音量设置
        if (config.BGM) this.bgmVolume = config["BGM VOLUME"] / 100
        else this.bgmVolume = 0
        if (config.SOUND) this.soundVolume = config["SOUND VOLUME"] / 100
        else this.soundVolume = 0

        // 装填
        localSoundList.map(async (item) => {
            this.localAudioNumber++
            const playFn = useSound(item.url, {
                volume: this.soundVolume,
                onload: () => {
                    this.loadLocalAudioNumber++
                    this.formatLocalProgress(item.name)
                },
                onError: () => {
                    console.log("音频加载失败 name", item.name)
                },
            })
            this.localPlayList.push({
                name: item.name,
                val: playFn,
            })
        })
        localBgmList.map(async (item) => {
            this.localAudioNumber++
            const bgmFn = useSound(item.url, {
                loop: true, // bgm循环播放
                volume: this.bgmVolume,
                onload: () => {
                    this.loadLocalAudioNumber++
                    this.formatLocalProgress(item.name)
                },
                onError: () => {
                    console.log("音频加载失败 name", item.name)
                },
            })
            this.localBgmList.push({
                name: item.name,
                val: bgmFn,
            })
        })

        console.log("this.localPlayList", this.localPlayList)
        console.log("this.localBgmList", this.localBgmList)
    }

    playBgm(name: string, rePlay = false, switchLocal = false, playProgress = 0) {
        // switchLocal: true 本次为切换本地和网络资源 不进行同名判断
        if (!switchLocal && this.targetBgmName == name && !rePlay) return
        this.stopBgm()
        if (name == "battle") {
            // 播放战斗bgm
            if (this.battleBgmListLoaded.length == 0) name = "singleplay01" // 暂无可用战斗bgm 播放默认bgm
            else {
                let length = this.battleBgmListLoaded.length
                let index = _.random(0, length - 1)
                let battleBgm = this.battleBgmListLoaded[index]
                this.targetBgmName = battleBgm.name.split(".")[0]
                // this.battleBgmName = battleBgm.name;
                console.log("battleBgm", battleBgm)
                this.targetBgm = this.battleBgmList.find((item: any) => item.name == battleBgm.name).val
                this.targetBgm.currentTime = 0
                this.targetBgm.play()
                return battleBgm.name
            }
        }
        this.targetBgmName = name
        let targetBgm = this.localBgmList.find((item: any) => item.name == name)?.val
        this.targetBgm = targetBgm
        this.targetBgm.play()
    }

    playSound(name: string) {
        let targetSound = this.localPlayList.find((item: any) => item.name == name)?.val
        targetSound.play()
    }

    stopBgm() {
        if (this.targetBgm) {
            if (this.targetBgm.stop) {
                this.targetBgm.stop()
            } else if (this.targetBgm.pause) {
                this.targetBgm.pause()
                if (this.targetBgm.seek) this.targetBgm.seek(0)
                let index = this.battleBgmList.findIndex((item: any) => item.name == this.targetBgmName)
                if (index > -1) this.battleBgmList[index].val.currentTime = 0
            }
            this.targetBgmName = ""
            this.targetBgm = null
        }
    }

    changeVolume() {
        let config = getSoundConfig()
        let bgmVolume = config.BGM ? config["BGM VOLUME"] / 100 : 0
        let soundVolume = config.SOUND ? config["SOUND VOLUME"] / 100 : 0
        if (bgmVolume != this.bgmVolume) {
            this.bgmVolume = bgmVolume
            this.localBgmList.map((item: any) => {
                item.val.sound.volume(this.bgmVolume)
            })
            if (this.targetBgm) this.targetBgm.sound.volume(this.bgmVolume)
        }
        if (soundVolume != this.soundVolume) {
            this.soundVolume = soundVolume
            this.localPlayList.map((item: any) => {
                item.val.sound.volume(this.soundVolume)
            })
        }
    }

    formatLocalProgress(name: string) {
        let val = ((this.loadLocalAudioNumber / this.localAudioNumber) * 100).toString()
        this.loadProgress.value = parseInt(val)
        console.log("本地资源:" + name + "加载完成 本地资源加载进度: ", val + "%")
        if (this.loadProgress.value >= 100) {
            this.onLoadCallback()
            this.hasActionOnLoadCallback = true
            this.loadBattleBgm()
        }
    }

    async loadBattleBgm() {
        let res = (await fetch("battleBgmList")) as any
        res.map((i: any, index: number) => {
            let bgmFn = new Audio()
            bgmFn.src = baseUrl + i.url
            bgmFn.loop = true // 循环
            bgmFn.volume = this.bgmVolume // 音量
            bgmFn.addEventListener("canplay", () => {
                console.log("battleBgmList 音频加载成功 name", i.name, i.url)
                this.battleBgmList[index].loaded = true
            })
            bgmFn.addEventListener("error", () => {
                console.log("battleBgmList 音频加载失败 name", i.name, i.url)
            })
            let item = {
                ...i,
                val: bgmFn,
                loaded: false,
            }
            this.battleBgmList.push(item)
        })
        console.log("battleBgmList", this.battleBgmList)
    }

    // 获取已加载完毕的battleBgmList
    get battleBgmListLoaded() {
        return this.battleBgmList.filter((item: any) => item.loaded)
    }
}

initAudio()
app.initAudioBase(AudioBase) // 将AudioBase传给pinia 在pinia进行挂载
</script>

<style lang="scss" scoped></style>
